package tree;

import java.util.List;
import java.util.Map;

import special_tree.*;
import lexer.Token;
import lexer.TokenType;

/**
 * Implementation of the abstract factory TreeFactory.
 * @see tree.TreeFactory
 */
public class MyTreeFactory implements TreeFactory{

	/* (non-Javadoc)
	 * @see tree.TreeFactory#makeArrayAccess(lexer.Token, tree.Tree, java.util.List)
	 */
	public Tree makeArrayAccess(Token token, Tree leftHandAccess,
			List<Tree> indexList) {
		return new ArrayAccessTree(token, leftHandAccess, indexList);
	}

	/* (non-Javadoc)
	 * @see tree.TreeFactory#makeAssign(lexer.Token, tree.Tree, tree.Tree)
	 */
	public Tree makeAssign(Token token, Tree decl, Tree expr) {
		return new AssignTree(token, decl, expr);
	}

	/* (non-Javadoc)
	 * @see tree.TreeFactory#makeBinOp(lexer.Token, tree.Tree, tree.Tree)
	 */
	public Tree makeBinOp(Token token, Tree left, Tree right) {
		return new BinOpTree(token, left, right);
	}

	/* (non-Javadoc)
	 * @see tree.TreeFactory#makeBlock(tree.Tree[])
	 */
	public Tree makeBlock(Tree... trees) {
		return new BlockTree(new Token(-1,-1,TokenType.LIST,""), trees);
	}

	/* (non-Javadoc)
	 * @see tree.TreeFactory#makeBreakStatement(lexer.Token)
	 */
	public Tree makeBreakStatement(Token token) {
		return new BreakTree(token);
	}

	/* (non-Javadoc)
	 * @see tree.TreeFactory#makeCatch(lexer.Token, tree.Tree, tree.Tree)
	 */
	public Tree makeCatch(Token token, Tree param, Tree block) {
		return new CatchTree(token, param, block);
	}

	/* (non-Javadoc)
	 * @see tree.TreeFactory#makeClassDecl(lexer.Token, int, tree.Type[], tree.Type[], tree.Tree)
	 */
	public Tree makeClassDecl(Token token, int numberOfType, Type[] extendsArr,
			Type[] implementsArr, Tree body) {
		return new ClassDeclTree(token, numberOfType, extendsArr, implementsArr, body);
	}

	/* (non-Javadoc)
	 * @see tree.TreeFactory#makeClassInstanceCreation(lexer.Token, tree.Type, java.util.List)
	 */
	public Tree makeClassInstanceCreation(Token token, Type type,
			List<Tree> constructorParams) {
		return new ClassInstanceCreationTree(token, type, constructorParams);
	}

	/* (non-Javadoc)
	 * @see tree.TreeFactory#makeCond(lexer.Token, tree.Tree, tree.Tree, tree.Tree)
	 */
	public Tree makeCond(Token token, Tree cond, Tree trueExpr, Tree falseExpr) {
		return new CondTree(token, cond, trueExpr, falseExpr);
	}

	/* (non-Javadoc)
	 * @see tree.TreeFactory#makeConstructorDeclaration(java.util.List, lexer.Token, java.util.List, tree.Tree, tree.Tree, int)
	 */
	public Tree makeConstructorDeclaration(List<Modifiers> modifierList,
			Token token, List<Type> throwsList, Tree params, Tree body,
			int localMethodVar) {
		return new ConstructorDeclarationTree(modifierList, token, throwsList, params, body,
				localMethodVar);
	}

	/* (non-Javadoc)
	 * @see tree.TreeFactory#makeConstructorInvokation(lexer.Token, tree.Tree)
	 */
	public Tree makeConstructorInvokation(Token tok, Tree exprList) {
		return new ConstructorInvocationTree(tok, exprList);
	}

	/* (non-Javadoc)
	 * @see tree.TreeFactory#makeDecl(lexer.Token, tree.Type, int)
	 */
	public Tree makeDecl(Token ident, Type type, int localVar) {
		return new DeclTree(ident, type, localVar);
	}

	/* (non-Javadoc)
	 * @see tree.TreeFactory#makeDynamicTypeTest(lexer.Token, tree.Tree, tree.Type)
	 */
	public Tree makeDynamicTypeTest(Token tok, Tree left, Type right) {
		return new DynamicTypeTestTree(tok, left, right);
	}

	/* (non-Javadoc)
	 * @see tree.TreeFactory#makeEmptyStatement(lexer.Token)
	 */
	public Tree makeEmptyStatement(Token token) {
		return new EmptyStatementTree(token);
	}

	/* (non-Javadoc)
	 * @see tree.TreeFactory#makeExplicitTypeCast(lexer.Token, tree.Type, tree.Tree)
	 */
	public Tree makeExplicitTypeCast(Token token, Type toTyp, Tree expr) {
		return new ExplicitTypeCastTree(token, toTyp, expr);
	}

	/* (non-Javadoc)
	 * @see tree.TreeFactory#makeFieldAccess(lexer.Token, tree.Tree)
	 */
	public Tree makeFieldAccess(Token token, Tree leftHandAccess) {
		return new FieldAccessTree(token, leftHandAccess);
	}

	/* (non-Javadoc)
	 * @see tree.TreeFactory#makeForLoop(lexer.Token, tree.Tree, tree.Tree, tree.Tree, tree.Tree)
	 */
	public Tree makeForLoop(Token token, Tree forInit, Tree condExpr,
			Tree forUpdate, Tree bodyStmt) {
		return new ForLoopTree(token, forInit, condExpr, forUpdate, bodyStmt);
	}

	/* (non-Javadoc)
	 * @see tree.TreeFactory#makeGlobalDecl(java.util.List, lexer.Token, tree.Type, int)
	 */
	public Tree makeGlobalDecl(List<Modifiers> modifierList, Token ident,
			Type type, int numberOfInstVar) {
		return new GlobalDeclTree(modifierList, ident, type, numberOfInstVar);
	}

	/* (non-Javadoc)
	 * @see tree.TreeFactory#makeIf(lexer.Token, tree.Tree, tree.Tree)
	 */
	public Tree makeIf(Token token, Tree cond, Tree trueStmt) {
		return new IfTree(token, cond, trueStmt);
	}

	/* (non-Javadoc)
	 * @see tree.TreeFactory#makeIfElse(lexer.Token, tree.Tree, tree.Tree, tree.Tree)
	 */
	public Tree makeIfElse(Token token, Tree cond, Tree trueStmt, Tree falseStmt) {
		return new IfElseTree(token, cond, trueStmt, falseStmt);
	}

	/* (non-Javadoc)
	 * @see tree.TreeFactory#makeImport(lexer.Token[], java.util.Map, tree.Tree[])
	 */
	public Tree makeImport(Token[] mainClassName,
			Map<String, Tree> importFiles, Tree... classes) {
		return new ImportTree(mainClassName, importFiles, classes);
	}

	/* (non-Javadoc)
	 * @see tree.TreeFactory#makeInput(lexer.Token, tree.Type)
	 */
	public Tree makeInput(Token token, Type typ) {
		return new InputTree(token, typ);
	}

	/* (non-Javadoc)
	 * @see tree.TreeFactory#makeInterfaceDecl(lexer.Token, int, tree.Type[], tree.Tree)
	 */
	public Tree makeInterfaceDecl(Token token, int numberOfType,
			Type[] extendsArray, Tree body) {
		return new InterfaceDeclTree(token, numberOfType, extendsArray, body);
	}

	/* (non-Javadoc)
	 * @see tree.TreeFactory#makeLengthExpr(lexer.Token, lexer.Token, tree.Tree)
	 */
	public Tree makeLengthExpr(Token token, Token ident, Tree left) {
		return new LengthExprTree(token, ident, left);
	}

	/* (non-Javadoc)
	 * @see tree.TreeFactory#makeList(tree.Tree[])
	 */
	public Tree makeList(Tree... nodes) {
		return new ListTree(new Token(-1, -1, TokenType.LIST, ""), nodes);
	}

	/* (non-Javadoc)
	 * @see tree.TreeFactory#makeLiteral(lexer.Token)
	 */
	public Tree makeLiteral(Token token) {
		return new LiteralTree(token);
	}

	/* (non-Javadoc)
	 * @see tree.TreeFactory#makeLocalArrayAccess(lexer.Token, java.util.List)
	 */
	public Tree makeLocalArrayAccess(Token token, List<Tree> indexList) {
		return new LocalArrayAccessTree(token, indexList);
	}

	/* (non-Javadoc)
	 * @see tree.TreeFactory#makeLocalVarAccess(lexer.Token)
	 */
	public Tree makeLocalVarAccess(Token token) {
		return new LocalVarAccessTree(token);
	}

	/* (non-Javadoc)
	 * @see tree.TreeFactory#makeMethodDeclaration(java.util.List, lexer.Token, tree.Type, tree.Tree, java.util.List, tree.Tree, int)
	 */
	public Tree makeMethodDeclaration(List<Modifiers> modifierList,
			Token token, Type type, Tree params, List<Type> throwsList,
			Tree body, int localMethodVar) {
		return new MethodDeclarationTree(modifierList, token, type, params, throwsList,
				body, localMethodVar);
	}
	
	/* (non-Javadoc)
	 * @see tree.TreeFactory#makeMethodHeader(java.util.List, lexer.Token, tree.Type, tree.Tree, java.util.List)
	 */
	public Tree makeMethodHeader(List<Modifiers> modifierList, Token token,
			Type type, Tree params, List<Type> throwsList) {
		return new MethodHeaderTree(modifierList, token, type, params, throwsList);
	}

	/* (non-Javadoc)
	 * @see tree.TreeFactory#makeMethodInvocation(lexer.Token, tree.Tree, tree.Tree[])
	 */
	public Tree makeMethodInvocation(Token token, Tree leftHandObjectPath,
			Tree[] arguments) {
		return new MethodInvocationTree(token, leftHandObjectPath, arguments);
	}

	/* (non-Javadoc)
	 * @see tree.TreeFactory#makeMethodInvocationStaticWithinOwnClass(lexer.Token, tree.Tree[])
	 */
	public Tree makeMethodInvocationStaticWithinOwnClass(Token tok,
			Tree[] arguments) {
		return new MethodInvocationStaticWithinOwnClassTree(tok, arguments);
	}

	/* (non-Javadoc)
	 * @see tree.TreeFactory#makeNewArray(lexer.Token, tree.Type, java.util.List)
	 */
	public Tree makeNewArray(Token token, Type ty, List<Tree> arrayBounces) {
		return new NewArrayTree(token, ty, arrayBounces);
	}

	/* (non-Javadoc)
	 * @see tree.TreeFactory#makeOutput(lexer.Token, tree.Tree)
	 */
	public Tree makeOutput(Token token, Tree expr) {
		return new OutputTree(token, expr);
	}

	/* (non-Javadoc)
	 * @see tree.TreeFactory#makePostIncDec(lexer.Token, tree.Tree)
	 */
	public Tree makePostIncDec(Token token, Tree expr) {
		return new PostIncDecTree(token, expr);
	}

	/* (non-Javadoc)
	 * @see tree.TreeFactory#makePreIncDec(lexer.Token, tree.Tree)
	 */
	public Tree makePreIncDec(Token token, Tree expr) {
		return new PreIncDecTree(token, expr);
	}

	/* (non-Javadoc)
	 * @see tree.TreeFactory#makeProgram(lexer.Token[], java.util.Map, tree.Tree[])
	 */
	public Tree makeProgram(Token[] mainClassName,
			Map<String, Tree> importFiles, Tree... classes) {
		return new ProgramTree(mainClassName, importFiles, classes);
	}

	/* (non-Javadoc)
	 * @see tree.TreeFactory#makeReturn(lexer.Token, tree.Tree)
	 */
	public Tree makeReturn(Token token, Tree expr) {
		return new ReturnTree(token, expr);
	}

	/* (non-Javadoc)
	 * @see tree.TreeFactory#makeStaticInitializer(lexer.Token, tree.Tree)
	 */
	public Tree makeStaticInitializer(Token token, Tree block) {
		return new StaticInitializerTree(token, block);
	}

	/* (non-Javadoc)
	 * @see tree.TreeFactory#makeSuperAccess(lexer.Token, tree.Type)
	 */
	public Tree makeSuperAccess(Token token, Type ty) {
		return new SuperAccessTree(token, ty);
	}

	/* (non-Javadoc)
	 * @see tree.TreeFactory#makeSwitch(lexer.Token, tree.Tree, tree.Tree)
	 */
	public Tree makeSwitch(Token token, Tree expr, Tree body) {
		return new SwitchTree(token, expr, body);
	}

	/* (non-Javadoc)
	 * @see tree.TreeFactory#makeSwitchGroup(lexer.Token, tree.Tree, tree.Tree)
	 */
	public Tree makeSwitchGroup(Token token, Tree expr, Tree blockStatementList) {
		return new SwitchGroupTree(token, expr, blockStatementList);
	}

	/* (non-Javadoc)
	 * @see tree.TreeFactory#makeThisAccess(lexer.Token)
	 */
	public Tree makeThisAccess(Token token) {
		return new ThisAccessTree(token);
	}

	/* (non-Javadoc)
	 * @see tree.TreeFactory#makeThrowException(lexer.Token, tree.Tree)
	 */
	public Tree makeThrowException(Token token, Tree expr) {
		return new ThrowExceptionTree(token, expr);
	}

	/* (non-Javadoc)
	 * @see tree.TreeFactory#makeTry(lexer.Token, tree.Tree, tree.Tree, tree.Tree)
	 */
	public Tree makeTry(Token token, Tree tryBlock, Tree catchTree,
			Tree finallyBlock) {
		return new TryTree(token, tryBlock, catchTree, finallyBlock);
	}

	/* (non-Javadoc)
	 * @see tree.TreeFactory#makeUnOp(lexer.Token, tree.Tree)
	 */
	public Tree makeUnOp(Token token, Tree op) {
		return new UnOpTree(token, op);
	}

	/* (non-Javadoc)
	 * @see tree.TreeFactory#makeWhile(lexer.Token, tree.Tree, tree.Tree)
	 */
	public Tree makeWhile(Token token, Tree cond, Tree body) {
		return new WhileTree(token, cond, body);
	}

}
